package net.subaquatic;

import java.util.Collections;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;

/**
 * This SOAPHandler is necessary as Salesforce.com changes the endpoint once the
 * user is successfully logged into the system.  This is the standard way
 * (i.e. no private packages) that can be used to modify the web services endpoint
 * once login has succeeded.
 *
 * @author Jason Howk
 */
public class SfSoapHandler implements SOAPHandler<SOAPMessageContext> {
    static final Logger logger = Logger.getLogger("net.subaquatic.SfSoapHandler");
    private static String endpoint;

    @Override
    public Set getHeaders() {
        //logger.log(Level.INFO, "getHeaders()");
        return Collections.EMPTY_SET;
    }

    @Override
    public boolean handleMessage(SOAPMessageContext context) {
        logger.log(Level.INFO, "************************* SfSoapHandler HANDLE MESSAGE *****************************");
        Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        if (outboundProperty.booleanValue()) {
            logger.log(Level.INFO, "Outbound Message.");
            // Point to the proper address.
            if (endpoint != null && !endpoint.isEmpty()) {
                logger.log(Level.INFO, "Setting endpoint addr: {0}", endpoint);
                context.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpoint);
            }
        }
        return true;
    }

    @Override
    public boolean handleFault(SOAPMessageContext context) {
        return true;
    }

    @Override
    public void close(MessageContext context) {
        // Nothing yet.
    }

    /**
     * Gets the currently set endpoint.
     * @return The endpoint currently in use.
     */
    public String getEndpoint() {
        return endpoint;
    }

    /**
     * Sets the endpoint provided by SFDC upon successful login.
     * @param endpoint The new endpoint.
     */
    public static void setEndpoint(String endpoint) {
        SfSoapHandler.endpoint = endpoint;
        logger.log(Level.INFO, "Set Endpoint: {0}", SfSoapHandler.endpoint);
    }
}
